若依vue中字典执行过程浅析 您所在的位置:网站首页 dictslsp 原理 若依vue中字典执行过程浅析

若依vue中字典执行过程浅析

2024-07-06 11:21| 来源: 网络整理| 查看: 265

1.导入并使用插件DataDict /** * file:src/main.js */ // 字典数据组件 import DictData from '@/components/DictData' DictData.install() /** *file:src/components/DictData/index.js */ import Vue from 'vue' import DataDict from '@/utils/dict' import { getDicts as getDicts } from '@/api/system/dict/data' function install() { Vue.use(DataDict, { metas: { '*': { labelField: 'dictLabel', valueField: 'dictValue', request(dictMeta) { //注意这个 return getDicts(dictMeta.type).then(res => res.data) }, }, }, }) } export default { install, } 2. DataDict初始化字典数据 , 混入dict,传给监听器回调 //file:src/utils/dict/index.js import Dict from './Dict' import { mergeOptions } from './DictOptions' export default function(Vue, options) { mergeOptions(options) Vue.mixin({ data() { if (this.$options === undefined || this.$options.dicts === undefined || this.$options.dicts === null) { return {} } const dict = new Dict() dict.owner = this return { dict } }, created() { if (!(this.dict instanceof Dict)) { return } options.onCreated && options.onCreated(this.dict) this.dict.init(this.$options.dicts).then(() => { options.onReady && options.onReady(this.dict) this.$nextTick(() => { this.$emit('dictReady', this.dict) if (this.$options.methods && this.$options.methods.onDictReady instanceof Function) { this.$options.methods.onDictReady.call(this, this.dict) } }) }) }, }) } 3. dict.init(this.$options.dicts) 给dict 赋值 import Vue from 'vue' import { mergeRecursive } from "@/utils/rytech"; import DictMeta from './DictMeta' import DictData from './DictData' const DEFAULT_DICT_OPTIONS = { types: [], } /** * @classdesc 字典 * @property {Object} label 标签对象,内部属性名为字典类型名称 * @property {Object} dict 字段数组,内部属性名为字典类型名称 * @property {Array.} _dictMetas 字典元数据数组 */ export default class Dict { constructor() { this.owner = null this.label = {} this.type = {} } init(options) { if (options instanceof Array) { options = { types: options } } const opts = mergeRecursive(DEFAULT_DICT_OPTIONS, options) if (opts.types === undefined) { throw new Error('need dict types') } const ps = [] this._dictMetas = opts.types.map(t => DictMeta.parse(t)) this._dictMetas.forEach(dictMeta => { const type = dictMeta.type Vue.set(this.label, type, {}) Vue.set(this.type, type, []) if (dictMeta.lazy) { return } ps.push(loadDict(this, dictMeta)) }) return Promise.all(ps) } /** * 重新加载字典 * @param {String} type 字典类型 */ reloadDict(type) { const dictMeta = this._dictMetas.find(e => e.type === type) if (dictMeta === undefined) { return Promise.reject(`the dict meta of ${type} was not found`) } return loadDict(this, dictMeta) } } /** * 加载字典 * @param {Dict} dict 字典 * @param {DictMeta} dictMeta 字典元数据 * @returns {Promise} */ function loadDict(dict, dictMeta) { return dictMeta.request(dictMeta) .then(response => { const type = dictMeta.type let dicts = dictMeta.responseConverter(response, dictMeta) if (!(dicts instanceof Array)) { console.error('the return of responseConverter must be Array.') dicts = [] } else if (dicts.filter(d => d instanceof DictData).length !== dicts.length) { console.error('the type of elements in dicts must be DictData') dicts = [] } dict.type[type].splice(0, Number.MAX_SAFE_INTEGER, ...dicts) dicts.forEach(d => { Vue.set(dict.label[type], d.value, d.label) }) return dicts }) }

先判断了是不是数组 我这里this.$options.dicts是字典类型的数组 在这里插入图片描述 然后给了opt.types 用 mergeRecursive 将opt.types合并到 DEFAULT_DICT_OPTIONS

// 数据合并 export function mergeRecursive(source, target) { for (var p in target) { try { if (target[p].constructor == Object) { source[p] = mergeRecursive(source[p], target[p]); } else { source[p] = target[p]; } } catch(e) { source[p] = target[p]; } } return source; };

执行了 this._dictMetas = opts.types.map(t => DictMeta.parse(t)) 然后loadDict(this, dictMeta) load中调用了dictMeta.request

request(dictMeta) { return getDicts(dictMeta.type).then(res => res.data) }

最后push到空数组ps中统一执行

4.DictMeta 字典元数据 /** * @classdesc 字典元数据 * @property {String} type 类型 * @property {Function} request 请求 * @property {String} label 标签字段 * @property {String} value 值字段 */ export default class DictMeta { constructor(options) { this.type = options.type this.request = options.request, this.responseConverter = options.responseConverter this.labelField = options.labelField this.valueField = options.valueField this.lazy = options.lazy === true } } /** * 解析字典元数据 * @param {Object} options * @returns {DictMeta} */ DictMeta.parse= function(options) { let opts = null if (typeof options === 'string') { opts = DictOptions.metas[options] || {} opts.type = options } else if (typeof options === 'object') { opts = options } opts = mergeRecursive(DictOptions.metas['*'], opts) return new DictMeta(opts) } 5.DictOptions DictMeta的配置项

DictOptions是一个DictMeta的一个默认配置项 这里提供了默认的labelField等和一个请求函数和映射转换函数 要注意的是 labelField,valueField,request在上面已经被赋值了 如下

import { mergeRecursive } from "@/utils/rytech"; import dictConverter from './DictConverter' export const options = { metas: { '*': { /** * 字典请求,方法签名为function(dictMeta: DictMeta): Promise */ request: (dictMeta) => { console.log(`load dict ${dictMeta.type}`) return Promise.resolve([]) }, /** * 字典响应数据转换器,方法签名为function(response: Object, dictMeta: DictMeta): DictData */ responseConverter, labelField: 'label', valueField: 'value', }, }, /** * 默认标签字段 */ DEFAULT_LABEL_FIELDS: ['label', 'name', 'title'], /** * 默认值字段 */ DEFAULT_VALUE_FIELDS: ['value', 'id', 'uid', 'key'], } /** * 映射字典 * @param {Object} response 字典数据 * @param {DictMeta} dictMeta 字典元数据 * @returns {DictData} */ function responseConverter(response, dictMeta) { const dicts = response.content instanceof Array ? response.content : response if (dicts === undefined) { console.warn(`no dict data of "${dictMeta.type}" found in the response`) return [] } return dicts.map(d => dictConverter(d, dictMeta)) } export function mergeOptions(src) { mergeRecursive(options, src) } export default options


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有